home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / hardware / vb2091.lha / vb2091.c next >
Encoding:
C/C++ Source or Header  |  1995-02-22  |  9.4 KB  |  306 lines

  1. /* vb2091 0.2b (c) in 1994 by Volker Barthelmann */
  2.  
  3. #define __USE_SYSBASE 1
  4.  
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8.  
  9. #include <exec/execbase.h>
  10. #include <exec/memory.h>
  11. #include <exec/io.h>
  12. #include <exec/semaphores.h>
  13. #include <devices/trackdisk.h>
  14. #include <devices/timer.h>
  15. #include <dos/dosextens.h>
  16. #include <dos/filehandler.h>
  17. #include <dos/dostags.h>
  18.  
  19. #ifdef __SASC
  20. #include <proto/exec.h>
  21. #include <proto/dos.h>
  22. #endif
  23.  
  24. /*#include <clib/exec_protos.h>
  25. #include <clib/alib_protos.h>
  26. #include <clib/dos_protos.h>*/
  27.  
  28. #define MAXUNIT 8
  29.  
  30. char zahl[]="0123456789";
  31. struct IOStdReq *IO[MAXUNIT]={0,0,0,0,0,0,0,0};
  32. struct SignalSemaphore *ss;
  33.  
  34. #define DEV_BEGINIO (-30)
  35.  
  36. #define min(a,b)    ((a) < (b) ? (a) : (b))
  37.  
  38. #define STAY   1
  39. #define BROKEN 2
  40. #define SINGLEF 4
  41. #define NOCACHE 8
  42. #define NOWRITE 16
  43.  
  44. #ifdef __SASC
  45. void __asm (*oldbeginio)(register __a1 char *req,register __a6 char *dev);
  46. #else
  47. void            (*oldbeginio)(/*register char *req asm("a1"),
  48.                               register char *dev asm("a6")*/)=0;
  49. #endif
  50.  
  51.  
  52. void    *Unit[MAXUNIT]={0,0,0,0,0,0,0,0};
  53.  
  54. int SIZE=262144,msize,flags=0,UnitNr=0,unitmask=0;
  55. int MAXN=16,MIN1BUF=131072,MIN2BUF=65536;
  56. char *buffer;
  57.  
  58. #ifdef __SASC
  59. void __saveds __asm mybeginio(register __a1 struct IOStdReq *req,register __a6 struct Device *dev)
  60. {
  61. #else
  62. void mybeginio()
  63. {
  64.     register struct IOStdReq *req asm ("a1");
  65.     register struct Device *dev asm ("a6");
  66. #endif
  67.     struct IOStdReq *mreq;
  68.     struct Device *mdev;
  69.     struct MsgPort *port;
  70.     int actual,data,offset,length,lactual,ldata,flag,msize,un=-1;
  71.  
  72.     mdev=dev;mreq=req;
  73.     ObtainSemaphore(ss);
  74.  
  75.     for(flag=0;flag<MAXUNIT;flag++) if(req->io_Unit==Unit[flag]) un=flag;
  76.     if(un==-1) goto old;
  77.  
  78.     if((req->io_Command & 0xFF) == CMD_READ){
  79.         if((flags & BROKEN)==0 && (long) req->io_Data<16777216) goto old;
  80.         port=(struct MsgPort *)CreatePort(NULL,0);
  81.         IO[un]->io_Message.mn_ReplyPort=port;
  82.         actual=0;
  83.         length=mreq->io_Length;
  84. /*        if(length>=65536) msize=min(length/4,SIZE/2); else msize=min(length,SIZE/2);*/
  85.         if(length>MIN2BUF*MAXN){msize=min((length+MAXN-1)/MAXN,SIZE/2);}
  86.          else{if(length<MIN1BUF) msize=min(length,SIZE/2); else msize=min(MIN2BUF,SIZE/2);}
  87.         if(msize>=512) msize=msize&0xfffffe00;
  88.         offset=mreq->io_Offset;
  89.         data=(int) mreq->io_Data;
  90.         lactual=flag=0;ldata=data;
  91.         if(flags&NOCACHE) CacheControl(0,CACRF_EnableD);
  92.         do{
  93.             IO[un]->io_Offset=offset;
  94.             if(flags&SINGLEF){
  95.                 IO[un]->io_Length=min(SIZE,length);
  96.                 IO[un]->io_Data=buffer;
  97.             }else{
  98.                 IO[un]->io_Length=min(msize,length);
  99.                 if(flag==0) IO[un]->io_Data=buffer; else
  100.                   IO[un]->io_Data=buffer+SIZE/2;
  101.             }
  102.             IO[un]->io_Command=CMD_READ;
  103.             req=IO[un];dev=IO[un]->io_Device;
  104. #ifdef __SASC
  105.             oldbeginio((char *) req,(char *) dev);
  106. #else
  107.             oldbeginio();
  108. #endif
  109.             if((flags&SINGLEF)==0){
  110.                 if(flag!=0) CopyMem(buffer,(APTR) ldata,lactual);
  111.                 else CopyMem(buffer+SIZE/2,(APTR) ldata,lactual);
  112.             }
  113.             WaitIO((struct IORequest *) IO[un]);
  114.             actual+=IO[un]->io_Actual;lactual=IO[un]->io_Actual;
  115.             ldata=data;data+=IO[un]->io_Actual;
  116.             offset+=IO[un]->io_Actual;
  117.             length-=IO[un]->io_Actual;
  118.             flag=1-flag;
  119.             if(flags&SINGLEF) CopyMem(buffer,(APTR) ldata,lactual);
  120.  
  121.         }while(length>0 && IO[un]->io_Actual>=IO[un]->io_Length);
  122.         if((flags&SINGLEF)==0){
  123.             if(flag!=0) CopyMem(buffer,(APTR) ldata,lactual);
  124.             else CopyMem(buffer+SIZE/2,(APTR) ldata,lactual);
  125.         }
  126.         if(flags&NOCACHE) CacheControl(0xffffffff,CACRF_EnableD);
  127.         mreq->io_Actual=actual;
  128.         mreq->io_Error=IO[un]->io_Error;
  129.         DeletePort(port);
  130.         if((mreq->io_Flags & IOF_QUICK) ==0)
  131.             ReplyMsg(&mreq->io_Message);
  132.         ReleaseSemaphore(ss);
  133.         return;
  134.     }
  135.     if((req->io_Command & 0xFF) == CMD_WRITE){
  136.         if(flags&NOWRITE) goto old;
  137.         if((flags & BROKEN)==0 && (long) req->io_Data<16777216) goto old;
  138.         port=(struct MsgPort *)CreatePort(NULL,0);
  139.         IO[un]->io_Message.mn_ReplyPort=port;
  140.         actual=0;
  141.         length=mreq->io_Length;
  142.         offset=mreq->io_Offset;
  143.         data=(int) mreq->io_Data;
  144.         if(flags&NOCACHE) CacheControl(0,CACRF_EnableD);
  145.         do{
  146.             if(SIZE>=length) IO[un]->io_Length=length; else
  147.               IO[un]->io_Length=SIZE;
  148.             CopyMem((APTR) data,buffer,IO[un]->io_Length);
  149.             IO[un]->io_Offset=offset;
  150.             IO[un]->io_Data=buffer;
  151.             IO[un]->io_Command=CMD_WRITE;
  152.             req=IO[un];dev=IO[un]->io_Device;
  153. #ifdef __SASC
  154.             oldbeginio((char *) req,(char *) dev);
  155. #else
  156.             oldbeginio();
  157. #endif
  158.             WaitIO((struct IORequest *) IO[un]);
  159.             actual+=IO[un]->io_Actual;
  160.             data+=IO[un]->io_Actual;
  161.             offset+=IO[un]->io_Actual;
  162.             length-=IO[un]->io_Actual;
  163.         }while(length>0 && IO[un]->io_Actual>=IO[un]->io_Length);
  164.         if(flags&NOCACHE) CacheControl(0xffffffff,CACRF_EnableD);
  165.         mreq->io_Actual=actual;
  166.         mreq->io_Error=IO[un]->io_Error;
  167.         DeletePort(port);
  168.         if((mreq->io_Flags & IOF_QUICK) ==0)
  169.             ReplyMsg(&mreq->io_Message);
  170.         ReleaseSemaphore(ss);
  171.         return;
  172.     }
  173. old:
  174. #ifdef __SASC
  175.     oldbeginio((char *) req,(char *) dev);
  176. #else
  177.     oldbeginio();
  178. #endif
  179.     ReleaseSemaphore(ss);
  180.  
  181. }
  182.  
  183.  
  184. int
  185. main(int argc, char *argv[])
  186. {
  187.     long            tmp,op;
  188.     int             devopen,i;
  189.     struct MsgPort *iosink[MAXUNIT]={0,0,0,0,0,0,0,0};
  190.     char *Device="2nd.scsi.device",*p;
  191.  
  192.     tmp = 0;
  193. /*    IO = NULL;
  194.     iosink = NULL; */
  195.     devopen = 0;
  196.     Device = "2nd.scsi.device";
  197.     op=Output();
  198.     for(i=1; i<argc; i++){
  199.         /*printf("Arg: %d  %s: ",i,argv[i]);*/
  200.         if(!strcmp("BUFSIZE",argv[i])){
  201.             /*printf("Buffersize\n");*/SIZE=atoi(argv[++i])*1024;continue;}
  202.         if(!strcmp("MIN1BUF",argv[i])){
  203.             MIN1BUF=atoi(argv[++i])*1024;continue;}
  204.         if(!strcmp("MIN2BUF",argv[i])){
  205.             MIN2BUF=atoi(argv[++i])*1024;continue;}
  206.         if(!strcmp("MAXN",argv[i])){
  207.             MAXN=atoi(argv[++i]);continue;}
  208.         if(!strcmp("DEVICE",argv[i])){
  209.             /*printf("Device\n");*/ Device=argv[++i];continue;}
  210.         if(!strcmp("UNIT",argv[i])){
  211.             p=argv[++i];
  212.             while(*p!=0){
  213.                 if(*p<'0'||*p>'7') {Write(op,"You can only use unit 0..7!!\n",29L);exit(0);}
  214.                 unitmask|=1<<(*p-'0');
  215.                 p++;
  216.             }
  217.             continue;}
  218.         if(!strcmp("BROKEN",argv[i])){
  219.             flags|=BROKEN;continue;}
  220.         if(!strcmp("SINGLE",argv[i])){
  221.             flags|=SINGLEF;continue;}
  222.         if(!strcmp("NOCACHE",argv[i])){
  223.             flags|=NOCACHE;continue;}
  224.         if(!strcmp("NOWRITE",argv[i])){
  225.             flags|=NOWRITE;continue;}
  226.         Write(op,"Wrong argument: ",16L);
  227.         Write(op,argv[i],strlen(argv[i]));
  228.         Write(op,"\nPLEASE READ THE MANUAL !!\n",27L);
  229.         exit(0);
  230.     }
  231.  
  232.     Write(op,"vb2091 V0.2b (c) in 1994 by Volker Barthelmann\n",47L);
  233.     /*printf("Flags: %d  SIZE: %d  Device: %s\n",flags,SIZE,Device);*/
  234.     /*printf("unitmask: %d\n",unitmask);*/
  235.     for(i=0;i<MAXUNIT;i++){
  236.         if((unitmask&(1<<i))==0) continue;
  237.         iosink[i] = (struct MsgPort *)CreatePort(NULL, 0);
  238.         IO[i] = (struct IOStdReq *) CreateExtIO(iosink[i], sizeof (*IO[0]));
  239.         tmp = OpenDevice(Device, i, (struct IORequest *) IO[i], 0);
  240.  
  241.         if (tmp) {
  242.             Write(op,"Unable to open ",15L);
  243.             Write(op,Device,strlen(Device));
  244.             Write(op," Unit ",6L);Write(op,&(zahl[i]),1L);
  245.             Write(op,"\n",1L);
  246. /*            if(IO[i])DeleteExtIO((struct IORequest *) IO[i]);
  247.             if(iosink[i]) DeletePort(iosink[i]);  */
  248.             IO[i]=0;
  249.             continue;
  250.         } else{
  251.             Write(op,"Opened ",7L);
  252.             Write(op,Device,strlen(Device));
  253.             Write(op," Unit ",6L);Write(op,&(zahl[i]),1L);
  254.             Write(op,"\n",1L);
  255.  
  256.             devopen = 1;
  257.             /*printf("Opened %s unit %d\n",Device,i);*/
  258.  
  259.             SumLibrary((struct Library *) IO[i]->io_Device);
  260.             if(oldbeginio==NULL) oldbeginio = (void (* )()) SetFunction((struct Library *) IO[i]->io_Device, DEV_BEGINIO, (APTR) &mybeginio);
  261.             Unit[i]=IO[i]->io_Unit;
  262.         }
  263.     }
  264.     ss = (struct SignalSemaphore *)AllocMem(sizeof (struct SignalSemaphore), MEMF_PUBLIC);
  265.     if (!ss)
  266.         goto quit;
  267.     InitSemaphore(ss);
  268.  
  269.     if(flags&BROKEN)
  270.         buffer=(char *)AllocMem(SIZE,MEMF_24BITDMA|MEMF_FAST|MEMF_PUBLIC);
  271.     else
  272.         buffer=(char *)AllocMem(SIZE,MEMF_24BITDMA|MEMF_PUBLIC);
  273.  
  274.     if(buffer==0) {Write(op,"Cannot allocate buffer!!\n",25L);goto quit;}
  275.  
  276.  
  277.     if(devopen) Wait(SIGBREAKF_CTRL_C);
  278.  
  279. quit:
  280.  
  281.     ObtainSemaphore(ss);
  282.     for(i=MAXUNIT-1;i>=0;i--){
  283.         if(IO[i]) /*printf("Restoring Unit %d\n",i);*/
  284.         if(IO[i]) SetFunction((struct Library *) IO[i]->io_Device, DEV_BEGINIO, (APTR) oldbeginio);
  285.     }
  286.     ReleaseSemaphore(ss);
  287.  
  288.  
  289.     if(buffer)
  290.         FreeMem(buffer, SIZE);
  291.     if (ss)
  292.         FreeMem(ss, sizeof (struct SignalSemaphore));
  293.     for(i=0;i<MAXUNIT;i++){
  294.         if (devopen) {
  295.             if(IO[i]) CloseDevice((struct IORequest *) IO[i]);
  296.         }
  297.         if (IO[i])
  298.             DeleteExtIO((struct IORequest *) IO[i]);
  299.         if (iosink[i])
  300.             DeletePort(iosink[i]);
  301.     }
  302.  
  303.     return 0;
  304. }
  305.  
  306.